package com.example.server.db.dao

import com.example.commons.models.AppVersion
import com.example.server.db.DatabaseFactory.dbQuery
import com.example.server.db.tables.AppVersions
import org.jetbrains.exposed.sql.SortOrder
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.select

class AppVersionDao private constructor() {



//    suspend fun findLatest(): AppVersion? = dbQuery {
//        AppVersions.selectAll().fetchSize(1)
//            .orderBy(AppVersions.versionCode, SortOrder.DESC_NULLS_FIRST)
//            .limit(1, 0)
//            .map(::resultRowToAppVersion)
//            .firstOrNull()
////        AppVersions.select {
////            Op.TRUE
////        }.orderBy(AppVersions.versionCode, SortOrder.DESC_NULLS_FIRST)
////            .fetchSize(1)
////            .map(::resultRowToAppVersion)
////            .firstOrNull()
//        //SELECT APPVERSIONS.ID, APPVERSIONS."versionCode", APPVERSIONS."versionName", APPVERSIONS."applicationId", APPVERSIONS."variantName", APPVERSIONS."outputFile", APPVERSIONS."platformType", APPVERSIONS.DESCRIPTION, APPVERSIONS."createdAt" FROM APPVERSIONS WHERE TRUE ORDER BY APPVERSIONS."versionCode" DESC NULLS FIRST
//        //SELECT APPVERSIONS.ID, APPVERSIONS."versionCode", APPVERSIONS."versionName", APPVERSIONS."applicationId", APPVERSIONS."variantName", APPVERSIONS."outputFile", APPVERSIONS."platformType", APPVERSIONS.DESCRIPTION, APPVERSIONS."createdAt" FROM APPVERSIONS ORDER BY APPVERSIONS."versionCode" DESC NULLS FIRST LIMIT 1
//    }

    suspend fun findLatest(applicationId: String, code: Int, variantName: String?) = dbQuery {
        AppVersions.select {
            val op = AppVersions.versionCode.greater(code)
                .and(AppVersions.applicationId.eq(applicationId))
            if (variantName.isNullOrBlank()) {
                op
            } else {
                op and AppVersions.variantName.eq(variantName)
            }
        }
            .orderBy(AppVersions.versionCode, SortOrder.DESC)
            .fetchSize(1)
            .limit(1, 0)
            .map(AppVersions::resultRowToAppVersion)
            .firstOrNull()
    }

    suspend fun insert(app: AppVersion) = dbQuery {
        val insertStatement = AppVersions.insert {
            it[versionCode] = app.versionCode
            it[versionName] = app.versionName
            it[applicationId] = app.applicationId
            it[variantName] = app.variantName
            it[outputFile] = app.outputFile
            it[platformType] = app.platformType
            it[description] = app.description
//            it[createdAt] = app.createdAt.longValue
        }
        insertStatement.resultedValues?.singleOrNull()?.let(AppVersions::resultRowToAppVersion)
    }

    companion object {

        @Volatile
        private var INSTANCE: AppVersionDao? = null

        fun getInstance(): AppVersionDao = INSTANCE ?: synchronized(this) {
            INSTANCE ?: AppVersionDao().also { INSTANCE = it }
        }
    }
}